package chapter_1.udp_test;

import java.io.IOException;
import java.io.InterruptedIOException;
import java.net.*;

/**
 * @author fulv
 */
public class UDPClient {

    /**
     *     socket的最长阻塞时间
     */
    public static final int TIMEOUT = 3000;
    /**
     * 最大重试次数
     */
    public static final int MAXTRIES = 5;

    /**
     * 接收packet缓冲区最大长度
     */
    public static final int BUF_SIZE = 1024;

    public static void main(String[] args) throws IOException {
        //创建一个UDPSocket实例和UDPPacket实例
        InetAddress serverAddress = InetAddress.getByName("127.0.0.1");
        int serverPort = 8080;
        //在创建udp socket时无需指定目的地址
        DatagramSocket socket = new DatagramSocket();
        //设置socket的最长阻塞时间（单位为ms）
        socket.setSoTimeout(TIMEOUT);

        String sendStr = "Hello World! 你好中国";
        byte[] strBytes = sendStr.getBytes();
        //创建udp数据发送 packet，设置目标服务器的地址和端口号
        DatagramPacket packet = new DatagramPacket(strBytes, strBytes.length, serverAddress, serverPort);
        //创建udp数据接收packet
        DatagramPacket receivePacket = new DatagramPacket(new byte[BUF_SIZE],BUF_SIZE);

        /**
         *向服务器发送数据，并接收来自服务器的反馈数据
         *由于UDP协议不是可靠协议，可能在发送和接收过程中
         * 出现包丢失，所以要判断是否接收到了来自指定服务器的数据
         */

        boolean receiveResponse = false;
        int tries = 0;
        do{
            //向目标服务器发送数据
            socket.send(packet);
            //尝试接受服务器的反馈数据
            try{
                socket.receive(receivePacket);
                //判断接收的数据是否来自目标服务器
                if(!serverAddress.equals(receivePacket.getAddress())){
                    throw new IOException("接收到来自未知服务器的数据");
                }
                //成功接收数据
                receiveResponse = true;
            }catch(InterruptedIOException e){
                System.out.println("没有接收到来自目标服务器的数据");
                //尝试次数加一
                tries +=1;
                System.out.println("延时,剩余重发次数" + (MAXTRIES -tries));
            }
        }while(!(receiveResponse)&&(tries<MAXTRIES));

        //如果成功接收到数据
        if(receiveResponse){
            System.out.println("接收到来自服务器: " + receivePacket.getSocketAddress() + "的数据");
            System.out.println("接收到的数据为: " + new String(receivePacket.getData()));
        }else{
            System.out.println("没有接收到来自服务器的响应");
        }
        socket.close();
    }
}
